import { _decorator, BoxCollider2D, Button, Color, Component, Contact2DType, director, instantiate, Label, labelAssembler, Node, Prefab, ProgressBar, resources, RigidBody2D, sp, Sprite, SpriteFrame, tween, UITransform, v2, v3 } from 'cc';
import { Dictionary } from './Dictionary';
import { getDistance, randomNum } from './utils';
import { Enemy } from './Enemy';
import { PlayerBullet } from './PlayerBullet';
import { tagEnum } from './Enum';
import { UserInfo } from './UserInfo';
import { AudioMgr } from './AudioMgr';
const { ccclass, property } = _decorator;

@ccclass('GameMgr')
export class GameMgr extends Component {

    @property(Node)
    leftMoveBtn: Node;
    @property(Node)
    rightMoveBtn: Node;
    @property(Node)
    jumpBtn: Node;
    @property(Node)
    player: Node
    @property(Node)
    bg: Node;
    @property(ProgressBar)
    hpBar: ProgressBar;
    @property(Prefab)
    enemyPre: Prefab;
    @property(Prefab)
    playerBulletPre: Prefab;
    @property(Node)
    enemyRoot: Node;
    @property(Node)
    bulletRoot: Node;
    @property(Node)
    winPanel: Node;
    @property(Node)
    failPanel: Node;
    @property(Label)
    gateLevelLabel: Label;
    @property(Prefab)
    wall0Pre: Prefab;
    @property(Prefab)
    wall1Pre: Prefab;
    @property(Node)
    wallRoot: Node;
    @property(Node)
    setPanel: Node;

    @property([SpriteFrame])
    gameBgSfArr: SpriteFrame[] = [];

    static ins: GameMgr;
    isLeftMoveIng = false;
    isRightMoveIng = false;
    directionLeftOrRight = 0;//朝向,0右1左
    enemyId = 1;

    isWalkIng=false;
    maxHp = 25;
    isGamePause = false;

    moveSpeed = 230;
    enemyExistDic: Dictionary<number, Node> = new Dictionary();
    generateEnemyY = 0;//生成敌人的y轴位置,针对布局

    jumpNum = 0;//跳跃次数

    isGameIng = true;

    private playerHp = this.maxHp;

    set PlayerHp(value) {
        this.playerHp = value;
        if (this.playerHp <= 0) {
            this.gameOver();
            return
        }
        AudioMgr.ins.playOneShot("audio/hited");

        this.player.getChildByName("sp").getComponent(sp.Skeleton).color = Color.RED;

        this.scheduleOnce(() => {
            this.player.getChildByName("sp").getComponent(sp.Skeleton).color = Color.WHITE;
        }, 0.2)

        this.hpBar.progress = this.playerHp / this.maxHp;
    }
    get PlayerHp() {
        return this.playerHp;
    }

    protected onLoad(): void {
        GameMgr.ins = this;
    }
    start() {

        if (UserInfo.isAudioBgm) {
            setTimeout(() => {
                AudioMgr.ins.play("audio/bgm0");
            }, 500);
        }
        else{
            AudioMgr.ins.stop();

        }

        this.leftMoveBtn.on(Node.EventType.TOUCH_START, this.leftMoveBtnTOUCH_START, this);
        this.leftMoveBtn.on(Node.EventType.TOUCH_END, this.leftMoveBtnTOUCH_END, this);
        this.leftMoveBtn.on(Node.EventType.TOUCH_CANCEL, this.leftMoveBtnTOUCH_END, this);

        this.rightMoveBtn.on(Node.EventType.TOUCH_START, this.rightMoveBtnTOUCH_START, this);
        this.rightMoveBtn.on(Node.EventType.TOUCH_END, this.rightMoveBtnTOUCH_END, this);
        this.rightMoveBtn.on(Node.EventType.TOUCH_CANCEL, this.rightMoveBtnTOUCH_END, this);

        this.jumpBtn.on(Node.EventType.TOUCH_START, this.jumpBtnTOUCH_START, this);
        this.player.getComponent(BoxCollider2D).on(Contact2DType.BEGIN_CONTACT, this.playerTouch, this)

        this.generateEnemyY = this.enemyRoot.getComponent(UITransform).convertToNodeSpaceAR(this.player.getWorldPosition()).y;

        this.init();

    }

    //初始化界面
    init() {
        this.gateLevelLabel.string = "关卡：" + UserInfo.gateLevel;
        this.wallRoot.removeAllChildren();

        if (UserInfo.gateLevel == 1) {
            this.bg.getChildByName("bg").getComponent(Sprite).spriteFrame = this.gameBgSfArr[0];
        }
        else {
            this.bg.getChildByName("bg").getComponent(Sprite).spriteFrame = this.gameBgSfArr[1];
        }

        //初次生成的敌人
        this.generateEnemyAtRight(2);
        this.randomGenerateWall(9)
    }

    playerTouch(self, other) {
        console.log("other", other.tag)
        if (other.tag == tagEnum.winTriggerNode) {
            this.gameWin();
        }
        if (other.tag == tagEnum.round) {
            if (this.jumpNum>0) {
                this.jumpNum = 0;

                if (this.isWalkIng) {
                    this.player.getChildByName("sp").getComponent(sp.Skeleton).setMix("jump_loop","_walk",0.1);
                    this.player.getChildByName("sp").getComponent(sp.Skeleton).setAnimation(0, "_walk", true);
                }
                else{
                    this.player.getChildByName("sp").getComponent(sp.Skeleton).setMix("jump_loop","_ship_sit",0.1);
                    this.player.getChildByName("sp").getComponent(sp.Skeleton).setAnimation(0, "_ship_sit", true);
                }
            
            }

        }
    }

    gameWin() {

        if (this.isGameIng) {
            this.isGameIng = false;
            console.log("游戏胜利")
            this.isGamePause = true;

            UserInfo.gateLevel += 1;
            this.saveGameData();

            this.winPanel.active = true;
        }

    }

    winPanelOnclickNextLevel() {
        AudioMgr.ins.playOneShot("audio/click");
        this.isGameIng = true;
        this.isGamePause = false;
        this.winPanel.active = false;
        this.failPanel.active = false;
        this.initGame();
    }

    gameOver() {
        if (this.isGameIng) {
            this.isGameIng = false;
            AudioMgr.ins.playOneShot("audio/fail");

            this.isGamePause = true;
            this.failPanel.active = true;
        }
    }

    failPanelOnclickRestartBtn() {
        AudioMgr.ins.playOneShot("audio/click");

        this.isGameIng = true;
        this.isGamePause = false;
        this.failPanel.active = false;
        this.winPanel.active = false;
        this.initGame();
    }

    initGame() {
        this.enemyExistDic.clear();
        this.enemyId = 0;
        this.playerHp = this.maxHp;
        this.hpBar.progress = 1;

        this.bulletRoot.removeAllChildren();
        this.enemyRoot.removeAllChildren();
        this.player.setPosition(-92, -100);
        this.bg.setPosition(-667, 275, 0);

        this.init();

    }


    leftMoveBtnTOUCH_START() {
        this.isWalkIng=true;
        this.player.setScale(v3(-1, 1, 1));
        this.player.getChildByName("sp").getComponent(sp.Skeleton).setMix("_walk", "_ship_sit", 0.2);
        this.player.getChildByName("sp").getComponent(sp.Skeleton).setAnimation(0, "_walk", true);

        this.directionLeftOrRight = 1;
        this.isLeftMoveIng = true;
    }
    leftMoveBtnTOUCH_END() {
        this.isWalkIng=false;
        this.player.getChildByName("sp").getComponent(sp.Skeleton).setAnimation(0, "_ship_sit", true);
        this.isLeftMoveIng = false;
    }
    rightMoveBtnTOUCH_START() {
        this.isWalkIng=true;
        this.player.setScale(v3(1, 1, 1));

        this.player.getChildByName("sp").getComponent(sp.Skeleton).setMix("_walk", "_ship_sit", 0.2);
        this.player.getChildByName("sp").getComponent(sp.Skeleton).setAnimation(0, "_walk", true);

        this.directionLeftOrRight = 0;
        this.isRightMoveIng = true;
    }
    rightMoveBtnTOUCH_END() {
        this.isWalkIng=false;
        this.player.getChildByName("sp").getComponent(sp.Skeleton).setAnimation(0, "_ship_sit", true);

        this.isRightMoveIng = false;
    }
    jumpBtnTOUCH_START() {
        // if (this.directionLeftOrRight == 0) {
        //     this.player.getComponent(RigidBody2D).applyForceToCenter(v2(0, 8000), true)
        // }
        // else {
        //     if (this.player.position.x > 80) {
        //         this.bg.getPosition(this.tempPos2);
        //         this.tempPos2.x += 50;
        //         this.bg.setPosition(this.tempPos2)
        //         this.player.getComponent(RigidBody2D).applyForceToCenter(v2(0, 8000), true);

        //     }
        //     else {
        //         //玩家移动
        //         this.player.getComponent(RigidBody2D).applyForceToCenter(v2(1000, 8000), true);

        //     }
        // }
        this.player.getChildByName("sp").getComponent(sp.Skeleton).setAnimation(0, "jump_loop", true);
        if (this.jumpNum < 2) {
            AudioMgr.ins.playOneShot("audio/jump");

            if (this.jumpNum == 0) {
                this.player.getComponent(RigidBody2D).linearVelocity = v2(0, 10);

            }
            else if (this.jumpNum == 1) {
                this.player.getComponent(RigidBody2D).linearVelocity = v2(0, 10);

                // this.player.getComponent(RigidBody2D).applyForceToCenter(v2(0, 1500), true);
            }
            this.jumpNum += 1;
        }

    }

    tempCountGenerateEnemy = 0;
    tempCountShot = 0;

    tempPos = v3()
    tempPos1 = v3()
    tempPos2 = v3()
    protected update(dt: number): void {
        if (!this.isGamePause) {
            if (this.isLeftMoveIng) {
                if (this.player.position.x < -80) {
                    if (this.bg.position.x <= -667) {
                        this.bg.getPosition(this.tempPos1);
                        this.tempPos1.x += this.moveSpeed * dt;
                        this.bg.setPosition(this.tempPos1)
                    }
                    else {
                        //玩家移动
                        this.player.getPosition(this.tempPos);
                        this.player.setPosition(this.tempPos.x - (this.moveSpeed * dt), this.tempPos.y, 0)
                    }
                }
                else {
                    //玩家移动
                    this.player.getPosition(this.tempPos);
                    this.player.setPosition(this.tempPos.x - (this.moveSpeed * dt), this.tempPos.y, 0)
                }

            }

            if (this.isRightMoveIng) {
                if (this.player.position.x > 80) {
                    if (this.bg.position.x >= -7300) {
                        this.bg.getPosition(this.tempPos2);
                        this.tempPos2.x -= this.moveSpeed * dt;
                        this.bg.setPosition(this.tempPos2)
                    }
                    else {
                        //玩家移动
                        this.player.getPosition(this.tempPos);
                        this.player.setPosition(this.tempPos.x + (this.moveSpeed * dt), this.tempPos.y, 0)
                    }
                }
                else {
                    //玩家移动
                    this.player.getPosition(this.tempPos);
                    this.player.setPosition(this.tempPos.x + (this.moveSpeed * dt), this.tempPos.y, 0)
                }

            }

            //生成敌人
            this.tempCountGenerateEnemy += dt;

            if (this.tempCountGenerateEnemy > 6) {
                this.tempCountGenerateEnemy = 0;
                this.generateEnemy(randomNum(1, 2));
            }

            //发射子弹
            this.tempCountShot += dt;

            if (this.tempCountShot > 0.6) {
                this.tempCountShot = 0;
                this.generatePlayerBullet();
            }
        }

    }

    generatePlayerBullet() {

        let tarNode = null;
        tarNode = GameMgr.ins.getNearlyExistOneEnemyNode();
        if (tarNode) {
            AudioMgr.ins.playOneShot("audio/shot");
            let tarPos = this.bulletRoot.getComponent(UITransform).convertToNodeSpaceAR(tarNode.getWorldPosition());
            let pre = instantiate(this.playerBulletPre);
            pre.setParent(this.bulletRoot);
            pre.setPosition(this.player.position.x + 15, this.player.position.y - 12);
            pre.getComponent(PlayerBullet).init(tarPos);
        }

    }


    generateEnemy(num) {
        for (let i = 0; i < num; i++) {
            let pre = instantiate(this.enemyPre);
            pre.setParent(this.enemyRoot);
            let rand = randomNum(0, 1);
            if (rand == 0) {
                let posX = this.enemyRoot.getComponent(UITransform).convertToNodeSpaceAR(this.player.getWorldPosition()).x + 1000;
                if (posX > 7250) {
                    posX = 7250;
                }
                pre.setPosition(posX, this.generateEnemyY)
            }
            else {
                let posX = this.enemyRoot.getComponent(UITransform).convertToNodeSpaceAR(this.player.getWorldPosition()).x + 1000;
                if (posX < -627) {
                    posX = -627;
                }
                pre.setPosition(posX, this.generateEnemyY)
            }
            this.enemyExistDic.set(this.enemyId, pre);
            this.enemyId += 1;
        }

    }

    generateEnemyAtRight(num) {
        for (let i = 0; i < num; i++) {
            let pre = instantiate(this.enemyPre);
            pre.setParent(this.enemyRoot);
            let rand = randomNum(0, 1);
            pre.setPosition(this.player.position.x + 1000, this.generateEnemyY)
            this.enemyExistDic.set(this.enemyId, pre);
            this.enemyId += 1;
        }

    }

    /**
    * @description: 得到场上最近一个敌人node
    * @return {*}
    */
    getNearlyExistOneEnemyNode() {
        let maxNearlyNode;
        let nearlyDistance = 0;
        if (this.enemyExistDic.lenght <= 0) {
            return null
        }

        this.enemyExistDic.getValueList().forEach((ele) => {
            if (this.directionLeftOrRight == 0) {//右
                if (ele.getWorldPosition().x < this.player.getWorldPosition().x) {
                    return
                }
            }
            else {//左
                if (ele.getWorldPosition().x > this.player.getWorldPosition().x) {
                    return
                }
            }
            if (maxNearlyNode == null) {
                maxNearlyNode = ele;
                nearlyDistance = getDistance(maxNearlyNode.position.x, 0, this.enemyRoot.getComponent(UITransform).convertToNodeSpaceAR(this.player.getWorldPosition()).x, 0);
            }
            else {
                if (nearlyDistance > getDistance(ele.position.x, 0, this.enemyRoot.getComponent(UITransform).convertToNodeSpaceAR(this.player.getWorldPosition()).x, 0)) {
                    maxNearlyNode = ele
                }
            }
        })

        //判断一下是否到达攻击距离
        if (maxNearlyNode) {
            if (getDistance(maxNearlyNode.position.x, 0, this.enemyRoot.getComponent(UITransform).convertToNodeSpaceAR(this.player.getWorldPosition()).x, 0) > 600) {
                maxNearlyNode = null;
            }
        }

        return maxNearlyNode;
    }

    randomGenerateWall(num) {
        for (let i = 0; i < num; i++) {
            let randcount = randomNum(0, 1);
            if (randcount == 0) {
                let pre = instantiate(this.wall0Pre);
                pre.setParent(this.wallRoot)
                pre.setPosition(randomNum(950, 7500), randomNum(-500,-480));
            }
            else {
                let pre = instantiate(this.wall1Pre);
                pre.setParent(this.wallRoot)
                pre.setPosition(randomNum(950, 7500), randomNum(-500,-480));
            }

        }

    }

    saveGameData() {
        let data = {
            gateLevel: UserInfo.gateLevel
        }
        localStorage.setItem("userInfo", JSON.stringify(data));
    }

    onclickSetBtn() {
        AudioMgr.ins.playOneShot("audio/click");

        this.setPanel.active = true;
        this.renewAudioUI();
    }

    onclickSetPanelHomeBtn() {
        // AudioMgr.ins.playOneShot("audio/click");
        director.loadScene("start");
        console.log("返回首页")
    }

    onclickSetPanelCloseBtn() {
        AudioMgr.ins.playOneShot("audio/click");

        this.setPanel.active = false;
    }

    onclickSetPanelAudioBtnBtn() {
        AudioMgr.ins.playOneShot("audio/click");

        if (UserInfo.isAudioEffect) {
            UserInfo.isAudioEffect=false;
            
        }
        else{
            UserInfo.isAudioEffect=true;
        }
        this.renewAudioUI();
    }

    onclickSetPanelMusicBtnBtn() {
        AudioMgr.ins.playOneShot("audio/click");

        if (UserInfo.isAudioBgm) {
            AudioMgr.ins.stop();
            UserInfo.isAudioBgm=false;

        }
        else{
            console.log("播放1")

            UserInfo.isAudioBgm=true;
            console.log("播放2")

            AudioMgr.ins.play("audio/bgm0");
            console.log("播放3")

        }
    
        this.renewAudioUI();
    }

    renewAudioUI() {
        if (UserInfo.isAudioBgm) {
            resources.load("audioImg/btn_music_on/spriteFrame", SpriteFrame, (err, res) => {
                this.setPanel.getChildByName("musicBtn").getComponent(Sprite).spriteFrame = res;

            })
        }
        else {
            resources.load("audioImg/btn_music_off/spriteFrame", SpriteFrame, (err, res) => {
                this.setPanel.getChildByName("musicBtn").getComponent(Sprite).spriteFrame = res;

            })
        }

        if (UserInfo.isAudioEffect) {
            resources.load("audioImg/btn_sound_on/spriteFrame", SpriteFrame, (err, res) => {
                this.setPanel.getChildByName("audioBtn").getComponent(Sprite).spriteFrame = res;

            })
        }
        else {
            resources.load("audioImg/btn_sound_off/spriteFrame", SpriteFrame, (err, res) => {
                this.setPanel.getChildByName("audioBtn").getComponent(Sprite).spriteFrame = res;

            })
        }
    }
}


